package org.itboys.trade.service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.itboys.commons.CommonConstants;
import org.itboys.commons.utils.time.TimeUtils;
import org.itboys.member.entity.Member;
import org.itboys.member.service.MemberService;
import org.itboys.mongodb.core.MongoDataSource;
import org.itboys.mongodb.service.BaseService;
import org.itboys.mongodb.utils.page.Page;
import org.itboys.mongodb.utils.query.QueryParamUtils;
import org.itboys.trade.constant.OrderConstant;
import org.itboys.trade.dto.OrderDto;
import org.itboys.trade.entity.Order;
import org.itboys.trade.tools.OrderNoBuildUtils;
import org.mongodb.morphia.mapping.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

/**
 * 订单
 * @author weisky
 *
 */
@Service
public class OrderService extends BaseService<Order, Long>{

	private static final long serialVersionUID = 1L;
	
	@Resource(name = "orderDS")
	private MongoDataSource ds;
	@Autowired
	private MemberService memberService;
//	@Autowired
//	private SellerService sellerService;
	@Autowired
	private OrderItemService orderItemService;
	
	public final static DecimalFormat df = new DecimalFormat("#.##");
	
	@Override
	protected MongoDataSource getMongoDataSource() {
		return ds;
	}

	@Override
	protected Class<Order> getEntityClass() {
		return Order.class;
	}
	
	/**
	 * 新增订单
	 * @param order
	 * @return
	 */
	public boolean insert(Order order){
		try{
			order.setStatus(OrderConstant.WAIT_SEND);//刚创建的订单，开始状态都是待发货
			order.setOrderNo(OrderNoBuildUtils.generanOrderNo());//设置订单编号
			save(order);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			logger.error("OrderService.insert error", e);
			logger.error("OrderService.insert error:Order={}", order);
			return false;
		}
	}
	
	/**
	 * 将order中一些字段组装到dto中  便于平台的展示
	 * @param request
	 * @return
	 */
	public Page<OrderDto> pageToDto(HttpServletRequest request){
		Map<String, Object> param = QueryParamUtils.builderQueryMap(request);
		Page<Order> page = super.pageQuery(param, request);
		Page<OrderDto> pageDto = new Page<OrderDto>();
		
		if(page != null && page.getData() != null){
			List<OrderDto> listDto = Lists.newArrayListWithExpectedSize(page.getData().size());
			for(Order order : page.getData()){
				listDto.add(diyOrderDto(order));//组装订单中的常用信息
			}
			pageDto.setTotal(page.getTotal());
			pageDto.setPageSize(page.getPageSize());
			pageDto.setData(listDto);
		}
		return pageDto;
	}
	
	/**
	 * 修改订单状态
	 * @param orderId
	 * @param status : 入参是字符，对应的是订单的状态
	 * @return
	 */
	public boolean updateStatus(Long orderId, String status){
		try{
			int temSt = OrderConstant.FAIL_CODE;
			switch (status) {
				case OrderConstant.PARAM_WAIT_SEND : temSt = OrderConstant.WAIT_SEND; break;
				case OrderConstant.PARAM_WAIT_RECEIVE : temSt = OrderConstant.WAIT_RECEIVE; break;
				case OrderConstant.PARAM_WAIT_APPRAISE : temSt = OrderConstant.WAIT_APPRAISE; break;
				case OrderConstant.PARAM_FINISH : temSt = OrderConstant.FINISH; break;
				case OrderConstant.PARAM_BACK : temSt = OrderConstant.BACK; break;
				case OrderConstant.PARAM_BACK_OK : temSt = OrderConstant.BACK_OK; break;
				case OrderConstant.PARAM_BACK_MONEY : temSt = OrderConstant.BACK_MONEY; break;
				case OrderConstant.PARAM_BACK_MONEY_OK : temSt = OrderConstant.BACK_MONEY_OK; break;
				case OrderConstant.PARAM_CANCEL : temSt = OrderConstant.CANCEL; break;
				default : temSt = OrderConstant.FAIL_CODE; break;
			}
			
			if(temSt != OrderConstant.FAIL_CODE){//开始修改订单状态
				super.update(orderId, "status", temSt);
			}else{
				logger.warn("OrderService.updateStatus warn 警告：将要修改的订单状态不存在！order={}， status={}", new Object[]{orderId, status});
				return false;
			}
			return true;
		}catch(Exception e){
			e.printStackTrace();
			logger.error("OrderService.updateStatus error:orderId="+orderId+"，status="+status, e);
			return false;
		}
	}
	
	/**
	 * 设置订单的物流信息
	 * @param orderId
	 * @param express
	 * @param expressNo
	 * @return
	 */
	public boolean setExpressInfo(Long orderId, String express, String expressNo){
		try{
			boolean result = true;
			int resu = super.update(orderId, "express", express);
			if(resu != 0){
				int resu2 = super.update(orderId, "expressNo", expressNo);
				if(resu2 == 0){
					result = false;
				}else{
					result = true;
				}
			}else{
				result = false;
			}
			
			if(!result){//如果设置失败，记录失败日志
				logger.error("OrderService.setExpressInfo error 设置订单的物流信息失败，orderId={}，express={}，expressNo={}", new Object[]{orderId,express,expressNo});
				return result;
			}
			//发货成功后，开始修改订单状态
			//注意：订单在任何状态下都可以发货，如果业务逻辑上有修改，到时候再修改代码
			boolean r = updateStatus(orderId, OrderConstant.PARAM_WAIT_RECEIVE);
			if(!r){//订单状态修改失败  模拟事物回滚  清除刚刚修改的快递信息
				super.update(orderId, "express", "");
				super.update(orderId, "expressNo", "");
				logger.error("OrderService.setExpressInfo error 设置订单物流信息成功，但修改订单状态失败，orderId={}，express={}，expressNo={}", new Object[]{orderId,express,expressNo});
				return false;
			}
			return result;
		}catch(Exception e){
			e.printStackTrace();
			logger.error("OrderService.setExpressInfo error 设置订单的物流信息失败，orderId="+orderId+"，express="+express+"，expressNo="+expressNo, e);
			return false;
		}
	}
	
	/**
	 * 组装订单中的常用信息
	 * @param order
	 * @return
	 */
	public OrderDto diyOrderDto(Order order){
		Member me = memberService.getById(order.getMemberId());
//		Seller s = sellerService.getById(order.getSellerId());
		OrderDto od = new OrderDto();
		od.setId(order.getId());
		od.setAddress(order.getAddress());
		od.setExpress(order.getExpress());
		od.setExpressNo(order.getExpressNo());
		od.setMemberName(me.getUsername());//会员名称就是会员的手机号
//		od.setSellerName(s.getName());
		od.setMobile(order.getMobile());//收货人手机号
		od.setName(order.getName());//收货人名称
		od.setOrderNo(order.getOrderNo());
		od.setPayTime(TimeUtils.format(order.getPayTime(), CommonConstants.DATE.FORMAT_DEFAULT));
		od.setStatus(order.getStatus());
		od.setTotalMoney(new BigDecimal(df.format(new BigDecimal(order.getTotalMoney()/100f))));//订单总金额
		return od;
	}

    public List<Order> getOrderListByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return ds.createQuery(getEntityClass()).field(Mapper.ID_KEY).in(ids).asList();
    }
}
